'Copyright (c) 2008, Jonathan Allen

Imports System.Runtime.CompilerServices
Imports System.Net
Imports ClrExtensions.Security
Imports ClrExtensions.Security.OAuth
Imports ClrExtensions.Net.Rest

''' <summary>
''' The NetflixConnection object contains the information needed to make REST calls to the Netflix servers
''' </summary>
''' <remarks></remarks>
Public Class NetflixConnection
	Private ReadOnly m_ConsumerKey As String
	Private ReadOnly m_ConsumerSecret As String
	Private ReadOnly m_Catalog As Catalog

	''' <summary>
	''' This is the Consumer Secret assigned to your application by Netflix.
	''' </summary>
	''' <value></value>
	''' <returns></returns>
	''' <remarks></remarks>
	Public ReadOnly Property ConsumerSecret() As String
		Get
			Return m_ConsumerSecret
		End Get
	End Property

	''' <summary>
	''' This is the Consumer Key assigned to your application by Netflix.
	''' </summary>
	''' <value></value>
	''' <returns></returns>
	''' <remarks></remarks>
	Public ReadOnly Property ConsumerKey() As String
		Get
			Return m_ConsumerKey
		End Get
	End Property

	''' <summary>
	''' Creates a new instance of the NetflixConnection using the application's consumer key and secret
	''' </summary>
	''' <param name="consumerKey">This is the Consumer Key assigned to your application by Netflix.</param>
	''' <param name="consumerSecret">This is the Consumer Secret assigned to your application by Netflix.</param>
	''' <remarks></remarks>
	Public Sub New(ByVal consumerKey As String, ByVal consumerSecret As String)
		m_ConsumerKey = consumerKey
		m_ConsumerSecret = consumerSecret
		m_Catalog = New Catalog(Me)
	End Sub

	''' <summary>
	''' This method generates a Request Token for a specific user.
	''' </summary>
	''' <exception cref="NetflixException"></exception>
	''' <returns></returns>
	''' <remarks>This token has a URL that your end-user can use to approve your application. Once approved, the Request Token can be traded in for an Access Token.</remarks>
	Public Function GenerateRequestToken() As RequestToken
		Dim fullRequest = NetflixUrls.GetRequestToken().SignRestCall(ConsumerKey, ConsumerSecret)

		Dim request = fullRequest.CreateHttpWebRequest
		Try
			Dim response = request.GetResponse
			Dim data = New IO.StreamReader(response.GetResponseStream).ReadToEnd
			Return New RequestToken(data, Me)
		Catch ex As Net.WebException
			Throw NetflixException.ParseException(ex)
		End Try
	End Function

	''' <summary>
	''' Converts an approved Request Token for a user-specific Access Token.
	''' </summary>
	''' <param name="requestToken"></param>
	''' <returns></returns>
	''' <remarks>Do not call this method until after the user approves your application. Calling it to soon will foul the Request Token. </remarks>
	<Obsolete("Use RequestToken.ConvertToAccessToken")> Public Function GenerateAccessToken(ByVal requestToken As RequestToken) As AccessToken
		Return ConvertRequestToAccessToken(requestToken)
	End Function

	Friend Function ConvertRequestToAccessToken(ByVal requestToken As RequestToken) As AccessToken
		Dim fullRequest = NetflixUrls.GetAccessToken().SignRestCall(ConsumerKey, ConsumerSecret, requestToken.Token, requestToken.TokenSecret)
		Dim request = fullRequest.CreateHttpWebRequest
        Try
            Dim response = request.GetResponse
            Dim data = New IO.StreamReader(response.GetResponseStream).ReadToEnd
            Return New AccessToken(data)

        Catch ex As Net.WebException
            Throw NetflixException.ParseException(ex)
        End Try
	End Function

	''' <summary>
	''' This method makes a Netflix request and returns the results as a stream.
	''' </summary>
	''' <param name="resource"></param>
	''' <returns></returns>
	''' <remarks>Developers </remarks>
	Public Function RequestResourceStream(ByVal resource As RestCall) As IO.StreamReader
		Dim fullRequest = resource.SignRestCall(ConsumerKey, ConsumerSecret)

		Dim request = fullRequest.CreateHttpWebRequest
		Try
			Dim response = request.GetResponse
			Return New IO.StreamReader(response.GetResponseStream)
		Catch ex As Net.WebException
			Throw NetflixException.ParseException(ex)
		End Try
	End Function


	''' <summary>
	''' This method makes a Netflix request and returns the results as a string
	''' </summary>
	''' <param name="resource"></param>
	''' <returns></returns>
	''' <remarks></remarks>
	Public Function RequestResource(ByVal resource As RestCall) As String
		Dim fullRequest = resource.SignRestCall(ConsumerKey, ConsumerSecret)

		Dim request = fullRequest.CreateHttpWebRequest

		Try
			Dim response = request.GetResponse
			Dim data = New IO.StreamReader(response.GetResponseStream).ReadToEnd
			Return data

		Catch ex As Net.WebException
			Throw NetflixException.ParseException(ex)
		End Try
	End Function

    '''' <summary>
    '''' This method makes a Netflix request, signed with a user's token, and returns the results as a string
    '''' </summary>
    '''' <param name="resource"></param>
    '''' <param name="user"></param>
    '''' <returns></returns>
    '''' <remarks></remarks>
    'Public Function RequestResource(ByVal resource As RestCall, ByVal user As User) As String
    '       Return RequestResource(resource, user)
    'End Function

	''' <summary>
	''' This method makes a Netflix request, signed with a user's token, and returns the results as a string
	''' </summary>
	''' <param name="resource"></param>
	''' <param name="accessToken"></param>
	''' <returns></returns>
	''' <remarks></remarks>
    Public Function RequestResource(ByVal resource As RestCall, ByVal accessToken As IAccessToken) As String
        Dim fullRequest = resource.SignRestCall(ConsumerKey, ConsumerSecret, accessToken.Token, accessToken.TokenSecret)

        Dim request = fullRequest.CreateHttpWebRequest
        request.ContentLength = 0
        Try
            Dim response = request.GetResponse
            Dim data = New IO.StreamReader(response.GetResponseStream).ReadToEnd
            Return data

        Catch ex As Net.WebException
            Dim response = ex.Response
            Dim data = New IO.StreamReader(response.GetResponseStream).ReadToEnd
            Throw New Exception(data, ex)
        End Try
    End Function


	Public Function RequestXmlResource(ByVal resource As RestCall) As XElement
		Return XElement.Parse(RequestResource(resource))
	End Function

	''' <summary>
	''' This method makes a Netflix request, signed with a user's token, and returns the results as XML
	''' </summary>
	''' <param name="resource"></param>
	''' <param name="accessToken"></param>
	''' <returns></returns>
	''' <remarks></remarks>
    Public Function RequestXmlResource(ByVal resource As RestCall, ByVal accessToken As IAccessToken) As XElement
        Return XElement.Parse(RequestResource(resource, accessToken))
    End Function

	''' <summary>
	''' This returns a Catalog object, which is used to search the Netflix catalog
	''' </summary>
	''' <returns></returns>
	''' <remarks></remarks>
	Public ReadOnly Property Catalog() As Catalog
		Get
			Return m_Catalog
		End Get
	End Property

End Class
